package dao

import (
	"context"
	"database/sql"
	"encoding/base64"
	"errors"
	"fmt"
	"ruoyi-go-echo-ddd/internal/domain/model"
	"ruoyi-go-echo-ddd/internal/infrastructure/http/request"
	"ruoyi-go-echo-ddd/internal/infrastructure/persistence/config"
	"ruoyi-go-echo-ddd/internal/infrastructure/utils"

	"github.com/rs/zerolog"
	"github.com/spf13/cast"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// SysUserDaoImpl 系统用户Dao结构
type SysUserDaoImpl struct {
	Gorm        config.PrimaryDB
	DeptDao     *SysDeptDaoImpl
	PostDao     *SysPostDaoImpl
	RoleDao     *SysRoleDaoImpl
	UserRoleDao *SysUserRoleDaoImpl
	UserPostDao *SysUserPostDaoImpl
}

// NewSysUserDaoImpl 系统用户Dao创建
func NewSysUserDaoImpl(db config.PrimaryDB,
	d *SysDeptDaoImpl,
	p *SysPostDaoImpl,
	r *SysRoleDaoImpl,
	ur *SysUserRoleDaoImpl,
	up *SysUserPostDaoImpl,
) *SysUserDaoImpl {
	return &SysUserDaoImpl{
		Gorm:        db,
		DeptDao:     d,
		PostDao:     p,
		RoleDao:     r,
		UserRoleDao: ur,
		UserPostDao: up,
	}
}

func hashUserPassword(user *model.User) {
	hashPassword, _ := utils.HashPassword(user.UserPwd, bcrypt.DefaultCost)
	user.UserPwd = hashPassword
}

//goland:noinspection SqlResolve,SqlCaseVsIf,SqlNoDataSourceInspection,SqlDialectInspection
func (userDao *SysUserDaoImpl) Insert(ctx context.Context, user *model.User) (*model.User, error) {
	hashUserPassword(user)

	/*result := userDao.Gorm.WithContext(ctx).
			Raw(
				`INSERT INTO sys_user (dept_id, username, nickname, user_type, email, phone_no, sex, avatar,
	                      user_pwd, user_status, create_by, remarks, create_time)
			 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING id`,
				user.DeptId,
				user.Username,
				user.Nickname,
				user.UserType,
				user.Email,
				user.PhoneNo,
				user.Sex,
				user.Avatar,
				user.UserPwd,
				user.UserStatus,
				user.CreateBy,
				user.Remarks,
				model.LocalDateTimeNow(""),
			).Scan(&insertId)
		if result.Error != nil {
			zap.L().Sugar().Errorf("系统用户新增执行错误===%+v", result.Error)
			zerolog.DefaultContextLogger.Error().Err(result.Error).Msg("系统用户新增执行错误===")
			return nil, errors.New("系统用户新增失败")
		}

		if result.RowsAffected == 0 {
			return nil, errors.New("没有插入任何记录")
		}

	insertUser, err := userDao.SelectById(ctx, insertId)
	if err != nil {
		return nil, errors.New("系统用户新增失败")
	}*/

	if err := userDao.Gorm.WithContext(ctx).Create(user).Error; err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统用户新增执行错误===")
		return nil, fmt.Errorf("failed to create user: %w", err)
	}

	if user.Id != 0 {
		id := user.Id
		roleIds := user.RoleIds
		if len(roleIds) > 0 {
			var userRoleList []*model.SysUserRole
			for _, roleId := range roleIds {
				userRoleList = append(userRoleList, &model.SysUserRole{
					UserId:     id,
					RoleId:     roleId,
					CreateTime: model.LocalDateTimeNow(""),
				})
			}

			insertRoleCount, err := userDao.UserRoleDao.BatchInsert(ctx, userRoleList)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("新增用户角色失败===")
				return nil, errors.New("新增用户失败")
			}
			zerolog.DefaultContextLogger.Info().Msgf("新增用户角色返回条数===%d", insertRoleCount)
		}

		postIds := user.PostIds
		if len(postIds) > 0 {
			var userPostList []*model.SysUserPost
			for _, postId := range postIds {
				userPostList = append(userPostList, &model.SysUserPost{
					UserId:     id,
					PostId:     postId,
					CreateTime: model.LocalDateTimeNow(""),
				})
			}

			// 新增用户岗位
			insertPostCount, err := userDao.UserPostDao.BatchInsert(ctx, userPostList)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户岗位失败===")
				return nil, errors.New("新增用户失败")
			}
			zerolog.DefaultContextLogger.Info().Msgf("新增用户岗位返回条数===%d", insertPostCount)
		}
	}

	return user, nil
}

//goland:noinspection SqlResolve,SqlCaseVsIf,SqlNoDataSourceInspection,SqlDialectInspection
func (userDao *SysUserDaoImpl) Update(ctx context.Context, user *model.User) (int64, error) {
	hashUserPassword(user)
	result := userDao.Gorm.WithContext(ctx).Save(user)
	if result.Error != nil {
		zerolog.DefaultContextLogger.Error().Err(result.Error).Msg("系统用户更新失败===")
		return 0, errors.New("系统用户更新失败")
	}

	rowsAffected := result.RowsAffected
	if rowsAffected == 0 {
		return 0, errors.New("系统用户更新失败")
	}

	roleIds := user.RoleIds
	if len(roleIds) > 0 {
		var userRoleList []*model.SysUserRole
		for _, roleId := range roleIds {
			userRoleList = append(userRoleList, &model.SysUserRole{
				UserId:     user.Id,
				RoleId:     roleId,
				CreateTime: model.LocalDateTimeNow(""),
			})
		}
		// 先删除用户角色
		delRoleCount, err := userDao.UserRoleDao.DeleteByUserId(ctx, user.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户角色失败===")
			return 0, errors.New("删除用户角色失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("删除用户角色返回条数===%d", delRoleCount)

		insertRoleCount, err := userDao.UserRoleDao.BatchInsert(ctx, userRoleList)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("新增用户角色失败===")
			return 0, errors.New("新增用户角色失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("新增用户角色返回条数===%d", insertRoleCount)

	} else {
		delRoleCount, err := userDao.UserRoleDao.DeleteByUserId(ctx, user.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户角色失败===")
			return 0, errors.New("删除用户角色失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("删除用户角色返回条数===%d", delRoleCount)
	}

	postIds := user.PostIds
	if len(postIds) > 0 {
		var userPostList []*model.SysUserPost
		for _, postId := range postIds {
			userPostList = append(userPostList, &model.SysUserPost{
				UserId:     user.Id,
				PostId:     postId,
				CreateTime: model.LocalDateTimeNow(""),
			})
		}

		// 先删除用户岗位
		delPostCount, err := userDao.UserPostDao.DeleteByUserId(ctx, user.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户岗位失败===")
			return 0, errors.New("删除用户岗位失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("删除用户岗位返回条数===%d", delPostCount)
		// 新增用户岗位
		insertPostCount, err := userDao.UserPostDao.BatchInsert(ctx, userPostList)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户岗位失败===")
			return 0, errors.New("删除用户岗位失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("新增用户岗位返回条数===%d", insertPostCount)

	} else {
		delPostCount, err := userDao.PostDao.DeleteByUserId(ctx, user.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除用户岗位失败===")
			return 0, errors.New("删除用户岗位失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("删除用户岗位返回岗位ID===%d", delPostCount)
	}

	return rowsAffected, nil
}

func (userDao *SysUserDaoImpl) SelectById(ctx context.Context, id int64) (*model.User, error) {
	var userInfo *model.User
	if err := userDao.Gorm.WithContext(ctx).
		Model(&model.User{}).
		Select("*, mask_password(user_pwd) AS user_pwd").
		First(&userInfo, id).Error; err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统用户详情查询失败===")
		return nil, errors.New("系统用户详情查询失败")
	}

	if userInfo != nil {
		deptInfo, err := userDao.DeptDao.SelectById(ctx, userInfo.DeptId)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户部门失败")
		}
		if deptInfo != nil {
			userInfo.DeptName = deptInfo.DeptName
		}

		roleIds, err := userDao.RoleDao.SelectIdsByUserId(ctx, userInfo.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户角色ID切片失败")
		}
		userInfo.RoleIds = roleIds

		sysRoles, err := userDao.RoleDao.SelectAll(ctx)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("查询所有切片失败")
		}
		if model.IsAdmin(userInfo.Id) {
			userInfo.Roles = sysRoles
		} else {
			allRoleFilterAdmin, _ := userDao.RoleDao.SelectAllFilterAdmin(sysRoles, true)
			userInfo.Roles = allRoleFilterAdmin
		}

		postIds, err := userDao.PostDao.SelectPostIdsByUserId(ctx, userInfo.Id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户岗位ID切片失败")
		}
		userInfo.PostIds = postIds

		postList, err := userDao.PostDao.SelectAll(ctx)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("查询所有岗位切片失败")
		}
		userInfo.Posts = postList
	}

	return userInfo, nil
}

func (userDao *SysUserDaoImpl) SelectByUsername(ctx context.Context, username string) (*model.User, error) {
	var user *model.User
	if err := userDao.Gorm.WithContext(ctx).
		Select("*, mask_phone(phone_no) AS phone_no, mask_password(user_pwd) AS user_pwd").
		Where("username = ?", username).
		First(&user).Error; err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msgf("查询用户===%s错误", username)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			zerolog.DefaultContextLogger.Error().Err(err).Msgf("用户===%s不存在", username)
		}
		return nil, errors.New("查询用户错误，请稍后再试")
	}
	return user, nil
}

func (userDao *SysUserDaoImpl) DeleteById(ctx context.Context, id int64) (int64, error) {
	result := userDao.Gorm.WithContext(ctx).Delete(&model.User{}, id)
	if result.Error != nil {
		zerolog.DefaultContextLogger.Error().Err(result.Error).Msgf("系统用户ID===%d删除失败===", id)
		return 0, errors.New("系统用户删除失败")
	}

	userDelCount := result.RowsAffected
	if userDelCount > 0 {
		_, err := userDao.UserRoleDao.DeleteByUserId(ctx, id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除绑定角色失败")
		}
		_, err = userDao.PostDao.DeleteByUserId(ctx, id)
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除绑定岗位失败")
		}
	}

	return userDelCount, nil
}

func (userDao *SysUserDaoImpl) BatchInsert(ctx context.Context, list []*model.User) ([]int64, error) {
	for _, user := range list {
		user.CreateTime = model.LocalDateTimeNow("")
		hashUserPassword(user)
	}

	result := userDao.Gorm.WithContext(ctx).Create(list)
	if result.Error != nil {
		zerolog.DefaultContextLogger.Error().Err(result.Error).Msg("系统用户批量新增BatchInsert错误===")
		return nil, errors.New("系统用户批量新增失败")
	}

	var ids []int64
	for _, item := range list {
		ids = append(ids, item.Id)
	}

	zerolog.DefaultContextLogger.Info().Msgf("系统用户批量新增BatchInsert成功,成功条数===%d,返回ids===%+v", result.RowsAffected, ids)
	return ids, nil
}

func (userDao *SysUserDaoImpl) BatchDelete(ctx context.Context, ids []any) (int64, error) {
	result := userDao.Gorm.WithContext(ctx).
		//Model(&model.User{}).
		//Where("id IN(?)", ids).
		//Delete(nil)
		Delete(&model.User{}, ids)
	if result.Error != nil {
		zerolog.DefaultContextLogger.Error().Err(result.Error).Msg("系统用户批量删除错误")
		return 0, errors.New("系统用户批量删除失败")
	}

	userDelCount := result.RowsAffected
	if userDelCount > 0 {
		_, err := userDao.UserRoleDao.DeleteByUserIdList(ctx, utils.ToInt64Slice(ids))
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除绑定角色失败")
		}
		_, err = userDao.PostDao.DeleteByUserIdList(ctx, utils.ToInt64Slice(ids))
		if err != nil {
			zerolog.DefaultContextLogger.Error().Err(err).Msg("删除绑定岗位失败")
		}
	}

	return userDelCount, nil
}

func (userDao *SysUserDaoImpl) SelectPage(ctx context.Context, param *request.UserPageParam) ([]*model.User, int64, int64, error) {
	pageParam := utils.InitPageParam(param.Page, param.Size)

	// 初始化 GORM 查询
	db := userDao.Gorm.WithContext(ctx).Model(&model.User{})
	// 动态构建查询条件
	if param.Username != "" {
		db.Where(`username ILIKE ?`, "%"+param.Username+"%")
	}
	if param.Nickname != "" {
		db.Where(`nickname ILIKE ?`, "%"+param.Nickname+"%")
	}
	if param.PhoneNo != "" {
		db.Where(`phone_no ILIKE ?`, "%"+param.PhoneNo+"%")
	}
	if param.Sex != "" {
		db.Where("sex = ?", param.Sex)
	}
	if param.UserStatus != "" {
		db.Where("user_status = ?", param.UserStatus)
	}
	if param.DeptId != "" {
		db.Where("dept_id = ?", cast.ToInt64(param.DeptId))
	}

	// 时间范围处理
	if param.BeginTime != "" && param.EndTime != "" {
		if begin, end, err := utils.ParseTimeRange(param.BeginTime, param.EndTime); err == nil {
			db.Where("create_time BETWEEN ? AND ?", begin, end)
		}
	}

	// 查询总记录数
	var total int64
	if err := db.Count(&total).Error; err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统用户总记录数异常")
		return nil, 0, 0, errors.New("系统用户总记录数失败")
	}

	db = utils.SetOrder(db, param.Column, param.Order).
		Offset(int(pageParam.Offset)).Limit(int(pageParam.Size)).
		Select("*, mask_phone(phone_no) AS phone_no, mask_password(user_pwd) AS user_pwd")

	// 查询用户列表
	var list []*model.User
	if err := db.Find(&list).Error; err != nil {

		zerolog.DefaultContextLogger.Error().
			Err(err).
			Str("function", "SelectPage").
			Any("param", param).
			Msg("系统用户总记录数异常")
		return nil, 0, 0, errors.New("系统用户列表失败")
	}

	userDao.SetUserOtherInfo(list, ctx)

	return list, total, utils.CalcTotalPage(total, param.Size), nil
}

//goland:noinspection SqlResolve,SqlCaseVsIf,SqlNoDataSourceInspection
func (userDao *SysUserDaoImpl) SelectList(ctx context.Context, limit, offset int64) ([]*model.UserForExcel, error) {
	logger := zerolog.DefaultContextLogger
	result := userDao.Gorm.WithContext(ctx).Raw(
		`SELECT
				id,
				dept_id,
				username,
				nickname,
				CASE
					WHEN user_type = '00' THEN '系统用户'
					WHEN user_type = '01' THEN '普通用户'
					WHEN user_type = '02' THEN '测试用户'
					ELSE '其他用户'
				END AS user_type,
				CASE
					WHEN email IS NULL THEN ''
					ELSE email
				END AS email,
				CASE
					WHEN phone_no IS NULL THEN ''
					ELSE mask_phone(phone_no)
				END AS phone_no,
				CASE
					WHEN sex = '0' THEN '女'
					WHEN sex = '0' THEN '男'
					ELSE '其他'
				END AS sex,
				avatar,
				CASE
					WHEN user_pwd IS NULL THEN ''
					ELSE mask_password(user_pwd)
				END AS user_pwd,
				CASE
					WHEN user_status = '0' THEN '正常'
					ELSE '停用'
				END AS user_status,
				CASE
					WHEN create_by IS NULL THEN ''
					ELSE create_by
				END AS create_by,
				CASE
					WHEN create_time IS NOT NULL THEN to_char(create_time, 'YYYY-MM-DD HH24:MI:SS')
					ELSE ''
				END AS create_time,
				CASE
					WHEN update_by IS NULL THEN ''
					ELSE update_by
				END AS update_by,
				CASE
					WHEN update_time IS NOT NULL THEN to_char(update_time, 'YYYY-MM-DD HH24:MI:SS')
					ELSE ''
				END AS update_time,
				CASE
					WHEN remarks IS NULL THEN ''
					ELSE remarks
				END AS remarks,
				CASE
					WHEN del_flag = '0' THEN '正常'
					ELSE '删除'
				END AS del_flag
			FROM
				sys_user
			ORDER BY id DESC
			LIMIT $1 OFFSET $2`, limit, offset)

	if result.Error != nil {
		logger.Error().Err(result.Error).Msg("用户分页查询行数错误===")
		return nil, errors.New("查询数据失败")
	}

	rows, err := result.Rows()
	if err != nil {
		logger.Error().Err(err).Msg("用户分页查rows错误")
	}
	defer func(rows *sql.Rows) {
		if err = rows.Close(); err != nil {
			logger.Error().Err(err).Msg("用户分页row关闭错误")
		}
	}(rows)

	var list []*model.UserForExcel

	for rows.Next() {
		user := &model.UserForExcel{}
		if err = rows.Scan(
			&user.Id,
			&user.DeptId,
			&user.Username,
			&user.Nickname,
			&user.UserType,
			&user.Email,
			&user.PhoneNo,
			&user.Sex,
			&user.Avatar,
			&user.UserPwd,
			&user.UserStatus,
			&user.CreateBy,
			&user.CreateTime,
			&user.UpdateBy,
			&user.UpdateTime,
			&user.Remarks,
			&user.DelFlag,
		); err != nil {
			logger.Error().Err(err).Msg("用户分页row转换===")
			return nil, err
		}
		list = append(list, user)
	}

	return list, nil
}

//goland:noinspection SqlResolve,SqlCaseVsIf,SqlNoDataSourceInspection
func (userDao *SysUserDaoImpl) GetTotalCount(ctx context.Context) (int64, error) {
	var total int64
	result := userDao.Gorm.WithContext(ctx).Raw("SELECT COUNT(*) FROM sys_user").Scan(&total)
	if result.Error != nil {
		zerolog.DefaultContextLogger.Error().Err(result.Error).Msg("查询总条数错误===")
		return 0, result.Error
	}
	return total, nil
}

func (userDao *SysUserDaoImpl) Login(ctx context.Context, user *model.UserLogin) (*model.User, error) {
	logger := zerolog.DefaultContextLogger

	username := user.Username
	var loginUser *model.User
	if err := userDao.Gorm.WithContext(ctx).Where("username = ?", username).First(&loginUser).Error; err != nil {
		logger.Error().Err(err).Msgf("用户===%s登陆错误", username)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			logger.Error().Err(err).Msgf("用户===%s不存在", username)
			return nil, errors.New("登录错误，请稍后再试")
		}
		return nil, errors.New("系统错误，请稍后再试")
	}

	encodePwdByte, err := base64.StdEncoding.DecodeString(user.UserPwd)
	if err != nil {
		logger.Error().Err(err).Msg("用户登录密码Base64解码失败===")
		return nil, errors.New("密码格式无效")
	}

	// 通过密钥文件解密
	decryptPwdByte, err := utils.RsaDecrypt("private.pem", encodePwdByte)
	if err != nil {
		logger.Error().Err(err).Msg("用户登录RSA解密失败===")
		return nil, errors.New("系统错误，请稍后再试")
	}

	decryptPassword := string(decryptPwdByte)
	logger.Info().Msgf("解析用户登录的密码===%s", decryptPassword)

	// 验证密码hash是否通过
	isSame := utils.ComparePassword(loginUser.UserPwd, decryptPassword)
	logger.Info().Msgf("用户登录密码hash===%t", isSame)

	if !isSame {
		return nil, errors.New("用户名与密码不匹配")
	}

	logger.Debug().Msgf("用户===%s登录成功", username)
	loginUser.UserPwd = ""
	return loginUser, nil
}

func (userDao *SysUserDaoImpl) SelectAll(ctx context.Context) ([]*model.UserForExcel, error) {
	var (
		list    []*model.UserForExcel
		allData []*model.UserForExcel
		count   int64
		page    = 1
		size    = 10000
	)
	db := userDao.Gorm.WithContext(ctx).Model(&model.User{})
	if err := db.Count(&count).Error; err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("获取用户所有最后登录记录总条数错误")
		return nil, errors.New("获取用户所有登录总条数失败")
	}
	zerolog.DefaultContextLogger.Info().Msgf("获取用户所有登录总条数===%d,当前分页批数===%d", count, size)

	// 分页大小大于或等于总条数，则直接一次性查询
	if int64(size) >= count {
		allData, err := userDao.SelectAllList(ctx)
		if err != nil {
			return nil, errors.New("获取所有登录总条数失败")
		}
		zerolog.DefaultContextLogger.Info().Msgf("分页大小大于或等于总条数一次性查询所有数据的条数===%d", len(allData))
		return allData, nil
	}

	for {
		list = list[:0]
		list, err := userDao.SelectList(ctx, int64(size), int64((page-1)*size))
		if err != nil {
			return nil, err
		}
		zerolog.DefaultContextLogger.Info().Msgf("第%d次查询获取用户分页数据条数===%d", page, len(list))

		if len(list) == 0 {
			zerolog.DefaultContextLogger.Info().Msgf("第%d次查询获取用户分页数据条数为0退出循环", page)
			break
		}
		allData = append(allData, list...)
		page++
	}

	userDao.SetUserOtherInfoExcel(allData, ctx)
	return allData, nil
}

func (userDao *SysUserDaoImpl) SetUserOtherInfo(list []*model.User, ctx context.Context) {
	if len(list) > 0 {
		for _, user := range list {
			user.IsAdmin = model.IsAdmin(user.Id)
			deptInfo, err := userDao.DeptDao.SelectById(ctx, user.DeptId)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户部门名称失败")
				continue
			}
			if deptInfo != nil {
				user.DeptName = deptInfo.DeptName
			}

			postIds, err := userDao.PostDao.SelectPostIdsByUserId(ctx, user.Id)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户岗位ID切片失败")
				continue
			}
			postNameList, err := userDao.PostDao.SelectPostNameListByIds(ctx, postIds)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户岗位ID切片失败")
				continue
			}
			user.PostNameArray = postNameList

			nameListByUserId, err := userDao.RoleDao.SelectRoleNameListByUserId(ctx, user.Id)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户角色名称切片失败")
				continue
			}
			user.RoleNameArray = nameListByUserId
		}
	}
}

func (userDao *SysUserDaoImpl) SetUserOtherInfoExcel(list []*model.UserForExcel, ctx context.Context) {
	if len(list) > 0 {
		for _, user := range list {
			deptInfo, err := userDao.DeptDao.SelectById(ctx, user.DeptId)
			if err != nil {
				zerolog.DefaultContextLogger.Error().Err(err).Msg("查询用户部门名称失败")
				continue
			}
			if deptInfo != nil {
				user.DeptName = deptInfo.DeptName
			}
		}
	}
}

//goland:noinspection ALL
func (userDao *SysUserDaoImpl) SelectAllList(ctx context.Context) ([]*model.UserForExcel, error) {
	logger := zerolog.DefaultContextLogger
	result := userDao.Gorm.WithContext(ctx).Raw(
		`SELECT
				id,
				dept_id,
				username,
				nickname,
				CASE
					WHEN user_type = '00' THEN '系统用户'
					WHEN user_type = '01' THEN '普通用户'
					WHEN user_type = '02' THEN '测试用户'
					ELSE '其他用户'
				END AS user_type,
				CASE
					WHEN email IS NULL THEN ''
					ELSE email
				END AS email,
				CASE
					WHEN phone_no IS NULL THEN ''
					ELSE mask_phone(phone_no)
				END AS phone_no,
				CASE
					WHEN sex = '0' THEN '女'
					WHEN sex = '0' THEN '男'
					ELSE '其他'
				END AS sex,
				avatar,
				CASE
					WHEN user_pwd IS NULL THEN ''
					ELSE mask_password(user_pwd)
				END AS user_pwd,
				CASE
					WHEN user_status = '0' THEN '正常'
					ELSE '停用'
				END AS user_status,
				CASE
					WHEN create_by IS NULL THEN ''
					ELSE create_by
				END AS create_by,
				CASE
					WHEN create_time IS NOT NULL THEN to_char(create_time, 'YYYY-MM-DD HH24:MI:SS')
					ELSE ''
				END AS create_time,
				CASE
					WHEN update_by IS NULL THEN ''
					ELSE update_by
				END AS update_by,
				CASE
					WHEN update_time IS NOT NULL THEN to_char(update_time, 'YYYY-MM-DD HH24:MI:SS')
					ELSE ''
				END AS update_time,
				CASE
					WHEN remarks IS NULL THEN ''
					ELSE remarks
				END AS remarks,
				CASE
					WHEN del_flag = '0' THEN '正常'
					ELSE '删除'
				END AS del_flag
			FROM
				sys_user
			ORDER BY id DESC`)

	if result.Error != nil {
		logger.Error().Err(result.Error).Msg("用户分页查询行数错误===")
		return nil, errors.New("查询数据失败")
	}

	rows, err := result.Rows()
	if err != nil {
		logger.Error().Err(err).Msg("用户分页查rows错误")
	}
	defer func(rows *sql.Rows) {
		if err = rows.Close(); err != nil {
			logger.Error().Err(err).Msg("用户分页row关闭错误")
		}
	}(rows)

	var list []*model.UserForExcel

	for rows.Next() {
		user := &model.UserForExcel{}
		if err = rows.Scan(
			&user.Id,
			&user.DeptId,
			&user.Username,
			&user.Nickname,
			&user.UserType,
			&user.Email,
			&user.PhoneNo,
			&user.Sex,
			&user.Avatar,
			&user.UserPwd,
			&user.UserStatus,
			&user.CreateBy,
			&user.CreateTime,
			&user.UpdateBy,
			&user.UpdateTime,
			&user.Remarks,
			&user.DelFlag,
		); err != nil {
			logger.Error().Err(err).Msg("用户分页row转换===")
			return nil, err
		}
		list = append(list, user)
	}

	return list, nil
}
